import xml.etree.ElementTree
ET = xml.etree.ElementTree

def parse_map(file):

    events = "start", "start-ns", "end-ns"
    root = None
    ns_map = {}
    ns_env = []
    
    for event, elem in ET.iterparse(file, events):
        if event == "start-ns":
            ns_env.append(elem)
            a, b = elem
            ns_map[a] = b

        elif event == "end-ns":
            a, b = ns_env.pop()
            ns_map.pop(a)

        elif event == "start":
            if root is None:
                root = elem
            elem.ns_map = ns_map.copy()

    _canonical_ns(root, None)

    return ET.ElementTree(root)

def _canonical_ns(elem, parent):
    ##recursive for sub-nodes, deep first
    for sub_elem in elem.getchildren():
        canonical_ns(sub_elem, elem)

    ##fix up tag and atrributes of current node
    ##currently ns_map include global ns
    ns_reverse_map = {}
    for prefix, uri in elem.ns_map.items():
        ns_reverse_map[uri] = prefix
    def fixup(name):
        if name[0] != "{":
            return
        uri, tag = name[1:].split("}")
        if uri in ns_reverse_map:
            new_name = ns_reverse_map[uri] + ":" + tag
            if (new_name[0] == ":"):
                new_name = new_name[1:]
            return new_name
 
    name = fixup(elem.tag)
    if name:
        elem.tag = name

    for key, value in elem.items():
        name = fixup(key)
        if name:
            elem.set(name, value)
            del elem.attrib[key]

    ##trim ns_map to inclue only local ns
    if parent:
        for key in elem.ns_map.keys():
            if key in parent.ns_map:
                elem.ns_map.pop(key)

    ##set local ns to attribute
    for prefix, uri in elem.ns_map.items():
        xmlns = "xmlns"
        if prefix:
            xmlns = "xmlns:"
        elem.set(xmlns + prefix, uri)

def write_xmlns(elem, file):

    if not ET.iselement(elem):
        elem = elem.getroot()

    ET.ElementTree(elem).write(file, encoding='UTF-8')

if __name__ == '__main__':
    tree = parse_map('d:\config.xml')
    write_xmlns(tree, 'd:\config1.xml')
    root = tree.getroot()
    sec = root.getchildren()[2]
    realm = sec.getchildren()[1]
    rm = realm.getchildren()[2]
    print root.ns_map
